import Duck from 'extensible-duck'
import produce from 'immer'

const isFormValidSelector = (state, validFields) => {
  if (state.validForm.fields === undefined || state.validForm.fields === {}) {
    return false
  }
  const { fields } = state.validForm
  if (Object.keys(fields).length === 0) return false
  return Object.keys(state.validForm.fields).reduce(
    (pre, next) => pre
      && (state.validForm.fields[next].state === 'success'
        || (validFields !== undefined && !validFields.includes(next))),
    true,
  )
}
const submitValuesSelector = (state, params) => {
  if (state.validForm.fields === undefined) {
    return {}
  }
  return params.reduce((pre, next) => {
    pre[next.paramName] = state.validForm.fields[next.fieldName].value
    return pre
  }, {})
}
export default new Duck({
  namespace: 'admin',
  store: 'validForm',
  types: [
    'INIT_FORM',
    'INIT_FIELD',
    'RESET_FORM',
    'FIELD_CHANGE',
    'SET_FIELD_STATE',
    'SET_FIELD_MESSAGE',
    'SET_FIELD_TASK',
    'MULTY_SWITCH_TOOGLE_FIELD',
    'SEARCH_INPUT_CHANGE',
    'SEARCH_SELECT_CHANGE',
    'ORG_DATA',
  ],
  initialState: { fields: {} },
  reducer: produce((draft, action, duck) => {
    switch (action.type) {
      case duck.types.INIT_FORM:
        draft.fields = action.value
        draft.init = true
        break
      case duck.types.INIT_FIELD:
        draft.fields[action.value.name] = {
          value: action.value.value,
          state: action.value.state,
        }
        break
      case duck.types.RESET_FORM:
        draft.fields = {}
        break
      case duck.types.FIELD_CHANGE:
        draft.fields[action.fieldName].value = action.value
        draft.fields[action.fieldName].state = 'valid'
        draft.focus = action.fieldName
        break
      case duck.types.SET_FIELD_STATE:
        draft.fields[action.fieldName].state = action.state
        break
      case duck.types.SET_FIELD_MESSAGE:
        draft.fields[action.fieldName].errorMessage = action.errorMessage
        break
      case duck.types.SET_FIELD_TASK:
        draft.fields[action.fieldName].task = action.task
        break
      case duck.types.MULTY_SWITCH_TOOGLE_FIELD:
        draft.fields[action.fieldName].value[action.name] = action.value
        break
      case duck.types.SEARCH_INPUT_CHANGE:
        draft.fields[action.fieldName].query = action.value
        draft.fields[action.fieldName].state = 'valid'
        break
      case duck.types.SEARCH_SELECT_CHANGE:
        draft.fields[action.fieldName].value = action.value
        draft.fields[action.fieldName].state = 'success'
        break
      case duck.types.ORG_DATA:
        draft.orgData = action.data
        break
      default:
        break
    }
  }),
  selectors: {
    values: state => state.validForm.fields,
    formValues: state => state.validForm,
    field: (state, fieldName) => state.validForm.fields[fieldName],
    fieldValue: (state, fieldName) => {
      const field = state.validForm.fields[fieldName]
      if (field) {
        return field.value
      }
      return undefined
    },
    fieldInitValue: (state, fieldName) => {
      if (state.validForm.orgData) {
        return state.validForm.orgData[fieldName]
      }
      return undefined
    },
    fieldState: (state, fieldName) => state.validForm.fields[fieldName].state,
    fieldErrorMessage: (state, fieldName) => state.validForm.fields[fieldName].errorMessage,
    focusField: state => state.validForm.focus,
    fieldTask: (state, fieldName) => state.validForm.fields[fieldName].task,
    isFormInit: state => state.validForm.init === true,
    isFormValid: isFormValidSelector,
    isFormDataInit: state => state.validForm.orgData !== undefined,
    submitValues: submitValuesSelector,
  },
  creators: duck => ({
    actionInitForm: value => ({ type: duck.types.INIT_FORM, value }),
    actionInitField: value => ({ type: duck.types.INIT_FIELD, value }),
    actionResetForm: () => ({ type: duck.types.RESET_FORM }),
    actionFieldChange: (fieldName, value, rules) => ({
      type: duck.types.FIELD_CHANGE,
      fieldName,
      value,
      rules,
    }),
    actionSetFieldState: (fieldName, state) => ({
      type: duck.types.SET_FIELD_STATE,
      fieldName,
      state,
    }),
    actionSetFieldErrorMessage: (fieldName, errorMessage) => ({
      type: duck.types.SET_FIELD_MESSAGE,
      fieldName,
      errorMessage,
    }),
    actionSetFieldForkTask: (fieldName, task) => ({
      type: duck.types.SET_FIELD_TASK,
      fieldName,
      task,
    }),
    actionMultySwitchToogleField: (fieldName, name, value) => ({
      type: duck.types.MULTY_SWITCH_TOOGLE_FIELD,
      fieldName,
      name,
      value,
    }),
    actionSearchInputChange: (fieldName, value) => ({
      type: duck.types.SEARCH_INPUT_CHANGE,
      fieldName,
      value,
    }),
    actionSearchSelectChange: (fieldName, value) => ({
      type: duck.types.SEARCH_SELECT_CHANGE,
      fieldName,
      value,
    }),
    actionReciveQueryData: data => ({
      type: duck.types.ORG_DATA,
      data,
    }),
  }),
})
